
(function(window,document,Laya){
	var __un=Laya.un,__uns=Laya.uns,__static=Laya.static,__class=Laya.class,__getset=Laya.getset,__newvec=Laya.__newvec;
//class interpreter.BaseExpression
var BaseExpression=(function(){
	function BaseExpression(){
		this.name=null;
		this.value=null;
	}

	__class(BaseExpression,'interpreter.BaseExpression');
	var __proto=BaseExpression.prototype;
	__proto.run=function(scope){}
	return BaseExpression;
})()


/**
*大括号
*/
//class interpreter.Braces
var Braces=(function(){
	function Braces(){
		/**
		*开始的行数
		*/
		this.begin=0;
		/**
		*结束的行数
		*/
		this.end=0;
		/**
		*所有代码的数据
		*/
		this.content=null;
		/**
		*代码块
		*/
		this.block=null;
		/**
		*子节点块
		*/
		this.child=null;
		/**
		*父节点块
		*/
		this.parent=null;
	}

	__class(Braces,'interpreter.Braces');
	var __proto=Braces.prototype;
	/**
	*添加节点
	*@param n
	*/
	__proto.addChild=function(n){
		n.parent=this;this.child=this.child||[];
		this.child.push(n);
	}

	__proto.explain=function(str){
		var rs=Braces.callExpretion.exec(str);
		if(rs){
			var calleelist=rs[1].split(".");
			var params=!rs[2] ? null :rs[2].split(",");
			var j=0;
			var len=calleelist.length;
			var callExp=new CallExpression();
			if (len==1){
				callExp.callee=IdentifierExpression.create(calleelist[0]);
			}
			else if (len==2){
				var objstr=calleelist[0];
				var obj;
				if (objstr=="this"){
					obj=this.parent.block;
				}
				else {
					var temp=this;
					while(!((temp.block instanceof interpreter.FunctionExpression ))){
						temp=temp.parent;
						if(temp==null)break ;
					}
					if(temp&&(temp.block).defineMap){
						obj=(temp.block).defineMap[objstr]||IdentifierExpression.create(objstr);
					}
					else {
						obj=IdentifierExpression.create(objstr);
					}
				};
				var property=IdentifierExpression.create(calleelist[1]);
				var temp=new MemberExpression(obj,property);
				callExp.callee=temp;
				callExp.setParams(params,this.block||{});
				(this.block).body.push(callExp);
			}
			else {
				for (var len=calleelist.length;j < len;j++){}
			}
		}
		else{
			rs=Braces.regVar.exec(str);
			if(rs&&rs[2]){
				var varexp=new VariableExpression();
				varexp.id=IdentifierExpression.create(rs[3]);
				varexp.kind=rs[2];
			}
			else{
			}
		}
	}

	/**
	*准备解析
	*@param currentIndex 当前解析的行数{index:i}
	*/
	__proto.finish=function(currentIndex){
		if((this.block instanceof interpreter.FunctionExpression )){
			var b=Math.max(currentIndex.index,this.begin);
			for(var i=b+1;i<this.end;i++){
				var s=this.content[i];
				var rs=Braces.callExpretion.exec(s);
				if(rs){
					var calleelist=rs[1].split(".");
					var params=!rs[2]?null:rs[2].split(",");
					var j=0;
					var len=calleelist.length;
					var callExp=new CallExpression();
					if(len==1){
						callExp.callee=IdentifierExpression.create(calleelist[0]);
					}
					else if(len==2){
						var objstr=calleelist[0];
						var obj;
						if(objstr=="this"){
							obj=this.parent.block;
						}
						else{
							var temp=this;
							while(!((temp.block instanceof interpreter.FunctionExpression ))){
								temp=temp.parent;
								if(temp==null)break ;
							}
							if(temp&&(temp.block).defineMap){
								debugger;
								obj=(temp.block).defineMap[objstr]||IdentifierExpression.create(objstr);
							}
							else {
								obj=IdentifierExpression.create(objstr);
							}
						};
						var property=IdentifierExpression.create(calleelist[1]);
						var temp=new MemberExpression(obj,property);
						callExp.callee=temp;
						callExp.setParams(params,this.block||{});
						(this.block).body.push(callExp);
					}
					else{
						for(var len=calleelist.length;j<len;j++){}
					}
				}
			}
			if(this.parent&& (this.parent.block instanceof interpreter.ClassExpression )){
				(this.parent.block).addFun(this.block.name,this.block);
			}
			else{
				currentIndex.index=this.end;
			}
		}
		else {
			if (this.parent&& (this.parent.block instanceof interpreter.FunctionExpression )){
				(this.parent.block).body.push(this.block);
			}
		}
	}

	__static(Braces,
	['callExpretion',function(){return this.callExpretion=new RegExp("([\\w\\.]+)\\s*\\((.*)\\)\\s*;");},'regVar',function(){return this.regVar=new RegExp("((var|let)\\s+|)([\\w.]+)\\s*([=])\\s*([\\w.]+);$");}
	]);
	return Braces;
})()


//class interpreter.DynamicObject
var DynamicObject=(function(){
	function DynamicObject(cls){
		/**
		*上下文
		*/
		this.scope=null;
		this.clsExpress=null;
		this.scope=new Scope("this",null);
		this.clsExpress=cls;
		var ctor=cls.$constructor;
		debugger;
		ctor&&ctor.run(this.scope);
	}

	__class(DynamicObject,'interpreter.DynamicObject');
	return DynamicObject;
})()


//class interpreter.Paser
var Paser=(function(){
	function Paser(){}
	__class(Paser,'interpreter.Paser');
	Paser.parseALL=function(s){
		var rs;
		var cls;
		var all=s.split(Paser.lineReg);
		if(all){
			rs=Paser.classreg.exec(all[0]);
			if(!rs)throw "未发现class定义";
			cls=ClassExpression.create(rs[1]);
			var rootNode=new Braces();
			rootNode.begin=0;
			rootNode.block=cls;
			var currentNode=rootNode;
			var currentIndex={index:0};
			for(var i=1,n=all.length;i<n;i++){
				var temp=all[i];
				var funinfo=Paser.defineFun.exec(temp);
				if(funinfo){
					if (currentNode){
						var tempNode=new Braces();
						tempNode.begin=i;
						var fun;
						if(funinfo[1]=="if"){
							fun=new IfExpression();
							(fun).defineMap=(currentNode.block).defineMap;
							(fun).parseContion(funinfo[2]);
						}
						else{
							fun=new FunctionExpression();
							fun.name=funinfo[1];
							(fun).parserParams(funinfo[2]);
						}
						currentNode.addChild(tempNode);
						tempNode.block=fun;
						currentIndex.index=i;
						currentNode=tempNode;
					}
					else {
						throw "class 已结束";
					}
				}
				else {
					if (Paser.rightBraces.exec(temp)){
						if (currentNode){
							currentNode.end=i;
							currentNode.content=all;
							currentNode.finish(currentIndex);
							currentNode=currentNode.parent;
						}
						else {
							throw "大括号没有匹配 }"+i;
						}
					}
					else{
						currentNode.explain(all[i]);
						currentIndex.index=i;
					}
				}
			}
		}
		return cls;
	}

	__static(Paser,
	['classreg',function(){return this.classreg=new RegExp("^\\s*class\\s+(\\w+)\\s*{");},'lineReg',function(){return this.lineReg=new RegExp("[\r\n]","g");},'defineFun',function(){return this.defineFun=new RegExp("^\\s*(\\w+)\\s*\\((.*)\\){");},'rightBraces',function(){return this.rightBraces=new RegExp("^\\s*}$");}
	]);
	return Paser;
})()


//class interpreter.Scope
var Scope=(function(){
	function Scope(t,p){
		this.content={};
		this.prefix=null;
		this.type=null;
		this.parent=null;
		this.invasived=false;
		this.prefix='@';
		this.type=t;
		this.parent=p || null;
		this.content={};
		this.invasived=false;
	}

	__class(Scope,'interpreter.Scope');
	var __proto=Scope.prototype;
	__proto.$const=function(raw_name,value){
		var name=this.prefix+raw_name;
		var $var=this.content[name];
		if (!$var){
			this.content[name]=ScopeVar.create('const',value);
			return true;
		}
		else {
			return false;
		}
	}

	__proto.$var=function(raw_name,value){
		var name=this.prefix+raw_name;
		var scope=this;
		while (scope.parent!==null && scope.type!=='function'){
			scope=scope.parent;
		};
		var $var=scope.content[name];
		if (!$var){
			this.content[name]=ScopeVar.create('var',value);
			return true;
		}
		else {
			return false;
		}
	}

	__proto.$find=function(raw_name){
		var name=this.prefix+raw_name;
		if (this.content.hasOwnProperty(name)){
			return this.content[name];
		}
		else if (this.parent){
			return this.parent.$find(raw_name);
		}
		else {
			return null;
		}
	}

	__proto.$declar=function(kind,raw_name,value){
		switch (kind){
			case 'var':
				return this.$var(raw_name,value);
			case 'const':
				return this.$const(raw_name,value);
			default :
				return false;
			}
	}

	__proto.recover=function(){
		this.type=null;
		this.parent=null;
		for (var key in this.content){
			var d=this.content[key];
			d.recover();
		}
		Scope.pools.push(this);
	}

	Scope.create=function(t,p){
		var rs=Scope.pools.pop();
		if (rs){
			rs.type=t;
			rs.parent=p;
		}
		else {
			rs=new Scope(t,p);
		}
		return rs;
	}

	Scope.pools=[];
	return Scope;
})()


//class interpreter.ScopeVar
var ScopeVar=(function(){
	function ScopeVar(kind,value){
		this.kind=null;
		this.value=null;
		debugger;
		this.kind=kind;
		this.value=value;
	}

	__class(ScopeVar,'interpreter.ScopeVar');
	var __proto=ScopeVar.prototype;
	__proto.$get=function(){
		return this.value;
	}

	__proto.$set=function(value){
		if (this.value==='const'){
			return false;
		}
		else {
			this.value=value;
			return true;
		}
	}

	/**
	*回收
	*/
	__proto.recover=function(){
		ScopeVar.pools.push(this);
	}

	ScopeVar.create=function(kind,value){
		var rst=ScopeVar.pools.pop();
		if(rst){
			rst.kind=kind;
			rst.value=value;
		}
		else{
			rst=new ScopeVar(kind,value);
		}
		return rst;
	}

	ScopeVar.pools=[];
	return ScopeVar;
})()


/**
*赋值表达式
*/
//class interpreter.AssignmentExpression extends interpreter.BaseExpression
var AssignmentExpression=(function(_super){
	function AssignmentExpression(key){
		/**
		*左侧表达式
		*/
		this.left=null;
		/**
		*表达式类型 如=+=-=
		*/
		this.kind=null;
		/**
		*右侧表达式
		*/
		this.right=null;
		AssignmentExpression.__super.call(this);
		this.initkind(key);
	}

	__class(AssignmentExpression,'interpreter.AssignmentExpression',_super);
	var __proto=AssignmentExpression.prototype;
	/**
	*初始化kind函数指针
	*@param key
	*/
	__proto.initkind=function(key){
		switch (key){
			case "=":
				this.kind=this.kindeq;
				break ;
			default :
				break ;
			}
	}

	/**
	*执行
	*@param scope 上下文对象
	*@return
	*/
	__proto.run=function(scope){
		if((this.left instanceof interpreter.MemberExpression )){
			var left=this.left;
			var obj=left.object.run(scope);
			var property=left.computed?left.property.run(scope):left.property.name;
			this.kind(obj,property,scope);
		}
		return null;
	}

	/**
	*=
	*@param scope
	*@return
	*/
	__proto.kindeq=function(o,property,scope){
		o[property]=this.right.run(scope);
		return true;
	}

	return AssignmentExpression;
})(BaseExpression)


//class interpreter.CallExpression extends interpreter.BaseExpression
var CallExpression=(function(_super){
	function CallExpression(){
		/**
		*执行对象
		*/
		this.callee=null;
		/**
		*参数
		*/
		this.arguments=null;
		/**
		*参数
		*/
		this.args=null;
		this.needRun=null;
		CallExpression.__super.call(this);
		this.arguments=[];
		this.args=[];
		this.needRun=[];
	}

	__class(CallExpression,'interpreter.CallExpression',_super);
	var __proto=CallExpression.prototype;
	__proto.run=function(scope){
		var func=this.callee.run(scope);
		for (var i=0,n=this.needRun.length;i < n;i++){
			var t=this.needRun[i];
			this.args[t]=this.arguments[t].run(scope);
		}
		if ((this.callee instanceof interpreter.MemberExpression )){
			var obj=(this.callee).object;
			var object=obj.value?obj.value:obj.run(scope);
			return func.apply(object,this.args);
		}
		else {
			var this_val=scope.$find('this');
			return func.apply(this_val ? this_val.$get():null,this.args);
		}
	}

	/**
	*设置参数
	*@param arr
	*/
	__proto.setParams=function(arr,parent){
		if(!arr)return;
		var n=arr.length;
		for(var i=0;i<n;i++){
			var temp=arr[i];
			debugger;
			var t;
			if(temp){
				var d=parseFloat(temp);
				if(d==temp){
					this.args[i]=d;
					t=new LiteralExpression();
					this.arguments[i]=t;
					t.raw=temp;
					t.value=d;
				}
				else{
					var rs=CallExpression.strReg.exec(temp);
					if(rs){
						this.args[i]=rs[2];
						t=new LiteralExpression();
						this.arguments[i]=t;
						t.raw=temp;
						t.value=rs[2];
					}
					else{
						var calleelist=temp.split(".");
						var j=0;
						var len=calleelist.length;
						if(len==1){
							this.needRun.push(i);
							var tempStr=calleelist[0];
							var obj=(parent).defineMap[tempStr]||IdentifierExpression.create(tempStr);
							this.arguments[i]=obj;
						}
						else if(len==2){
							this.needRun.push(i);
							var tempStr0=calleelist[0];
							var tempStr1=calleelist[1];
							this.arguments[i]=new MemberExpression((parent).defineMap[tempStr0]||IdentifierExpression.create(tempStr0),(parent).defineMap[tempStr1]||IdentifierExpression.create(tempStr1));
						}
						else{
							console.log(">>>>>>>>>>>>TODO"+calleelist);
						}
					}
				}
			}
		}
	}

	__proto.parser=function(){}
	__proto.toString=function(){
		var rs="\t"+this.callee.toString()+"(";
		for(var i=0,n=this.arguments.length;i<n;i++){
			if(i!=0){
				rs+=",";
			}
			rs+=this.arguments[i].toString();
		}
		rs+=");\n";
		return rs;
	}

	__static(CallExpression,
	['strReg',function(){return this.strReg=new RegExp("(\"(.*)\")");}
	]);
	return CallExpression;
})(BaseExpression)


/**
*类
*/
//class interpreter.ClassExpression extends interpreter.BaseExpression
var ClassExpression=(function(_super){
	function ClassExpression(n){
		/**
		*构造函数
		*/
		this.$constructor=null;
		/**
		*函数集合
		*/
		this.funs=null;
		/**
		*函数map
		*/
		this.funMap=null;
		ClassExpression.__super.call(this);
		this.funs=[];
		this.funMap={};
		this.name=n;
	}

	__class(ClassExpression,'interpreter.ClassExpression',_super);
	var __proto=ClassExpression.prototype;
	/**
	*增加函数
	*@param name 函数名称
	*@param func 函数
	*/
	__proto.addFun=function(name,func){
		if(name=="constructor"){
			this.$constructor=func;
		}
		this.funMap[name]=func;
		this.funs.push(func);
	}

	/**
	*回收
	*/
	__proto.recover=function(){
		this.funs.length=0;
		this.funMap={};
		this.name=null;
		ClassExpression.pools.push(this);
	}

	__proto.createObject=function(){}
	__proto.toString=function(){
		var rs=
		"class "+this.name+"{\n";
		for(var i=0,n=this.funs.length;i<n;i++){
			rs+='\n';
			rs+=this.funs[i].toString();
			rs+='\n'
		}
		rs+="\n}";
		return rs;
	}

	ClassExpression.create=function(name){
		var rs=ClassExpression.pools.pop();
		if(rs){
			rs.name=name;
		}
		else {
			rs=new ClassExpression(name);
		}
		return rs;
	}

	ClassExpression.pools=[];
	return ClassExpression;
})(BaseExpression)


//class interpreter.FunctionExpression extends interpreter.BaseExpression
var FunctionExpression=(function(_super){
	function FunctionExpression(){
		this.body=null;
		this.params=null;
		this.defineMap=null;
		FunctionExpression.__super.call(this);
		this.body=[];
		this.params=[];
		this.defineMap={};
	}

	__class(FunctionExpression,'interpreter.FunctionExpression',_super);
	var __proto=FunctionExpression.prototype;
	__proto.run=function(scope){
		var new_scope=Scope.create('function',scope);
		var i=0;
		var n=this.params.length;
		if(n==1){
			this.params[0].value=arguments[1];
		}
		else {
			for (i=0;i < n;i++){
				var b=this.params[i];
				b.value=arguments[i+1];
			}
		}
		for(i=0,n=this.body.length;i<n;i++){
			this.body[i].run(new_scope);
		}
		new_scope.recover();
	}

	/**
	*初始化参数
	*@param array
	*/
	__proto.putParams=function(p){
		this.params.push(p);
	}

	/**
	*解析参数
	*@param s
	*/
	__proto.parserParams=function(s){
		s=s.replace(FunctionExpression.reg,"");
		if(s=="")return;
		var arr=s.split(",");
		for(var i=0,n=arr.length;i<n;i++){
			var temp=arr[i];
			var parm=IdentifierExpression.create(temp);
			this.params.push(parm);
			this.defineMap[temp]=parm;
		}
	}

	/**
	*返回字符串
	*@return
	*/
	__proto.toString=function(){
		var i=0,n=0;
		var rs=
		'\t'+this.name+"(";
		for(i=0,n=this.params.length;i<n;i++){
			if(i!=0)rs+=",";
			rs+=this.params[i].name;
		}
		rs+="){\n";
		for(i=0,n=this.body.length;i<n;i++){
			rs+="\t"+this.body[i].toString();
		}
		rs+='\n\t}';
		return rs;
	}

	__static(FunctionExpression,
	['reg',function(){return this.reg=new RegExp("\\s+","g");}
	]);
	return FunctionExpression;
})(BaseExpression)


/**
*变量
*/
//class interpreter.IdentifierExpression extends interpreter.BaseExpression
var IdentifierExpression=(function(_super){
	function IdentifierExpression(){
		IdentifierExpression.__super.call(this);
	}

	__class(IdentifierExpression,'interpreter.IdentifierExpression',_super);
	var __proto=IdentifierExpression.prototype;
	/**
	*回收
	*/
	__proto.recover=function(){
		this.clear();
		IdentifierExpression.pools.push(this);
	}

	/**
	*
	*@param scope
	*@return
	*/
	__proto.run=function(scope){
		if (this.name==='undefined'){
			return undefined;
		}
		if(this.value)return this.value;
		var $var=scope.$find(this.name);
		if ($var){
			return $var.$get();
		}
		else {
			throw "[Error] Identifier";
		}
	}

	/**
	*清理
	*/
	__proto.clear=function(){
		this.name=null;
		this.value=null;
	}

	__proto.toString=function(){
		return this.name;
	}

	IdentifierExpression.create=function(name){
		var rst=IdentifierExpression.pools.pop()||new IdentifierExpression();
		rst.name=name;
		return rst;
	}

	IdentifierExpression.pools=[];
	return IdentifierExpression;
})(BaseExpression)


//class interpreter.IfExpression extends interpreter.BaseExpression
var IfExpression=(function(_super){
	function IfExpression(){
		this.condition=null;
		this.body=null;
		IfExpression.__super.call(this);
		this.body=[];
	}

	__class(IfExpression,'interpreter.IfExpression',_super);
	var __proto=IfExpression.prototype;
	/**
	*解析if条件
	*@param s
	*/
	__proto.parseContion=function(s){}
	__proto.run=function(scope){
		var i=0,n=0;
		if(true||this.condition.run(scope)){
			for(i=0,n=this.body.length;i<n;i++){
				this.body[i].run(scope);
			}
		}
	}

	__proto.toString=function(){
		var i=0,n=0;
		var rs="if(){\n";
		for(i=0,n=this.body.length;i<n;i++){
			rs+="\t"+this.body[i].toString();
		}
		rs+="}\n";
		return rs;
	}

	return IfExpression;
})(BaseExpression)


//class interpreter.LiteralExpression extends interpreter.BaseExpression
var LiteralExpression=(function(_super){
	function LiteralExpression(){
		this.raw=null;
		LiteralExpression.__super.call(this);
	}

	__class(LiteralExpression,'interpreter.LiteralExpression',_super);
	var __proto=LiteralExpression.prototype;
	__proto.run=function(scope){
		return this.value;
	}

	__proto.parser=function(){}
	__proto.toString=function(){
		return this.raw;
	}

	return LiteralExpression;
})(BaseExpression)


//class interpreter.MemberExpression extends interpreter.BaseExpression
var MemberExpression=(function(_super){
	function MemberExpression(object,property){
		this.object=null;
		this.property=null;
		this.computed=false;
		MemberExpression.__super.call(this);
		this.object=object;
		this.property=property;
	}

	__class(MemberExpression,'interpreter.MemberExpression',_super);
	var __proto=MemberExpression.prototype;
	__proto.run=function(scope){
		var obj=this.object;
		var pro=this.property;
		if (this.computed){
			return this.object.run(scope)[pro.run(scope)]
		}
		else {
			return obj.value?obj.value[pro.name]:obj.run(scope)[pro.name];
		}
	}

	__proto.toString=function(){
		return this.object.toString()+"."+this.property.toString();
	}

	return MemberExpression;
})(BaseExpression)


//class interpreter.VariableExpression extends interpreter.BaseExpression
var VariableExpression=(function(_super){
	function VariableExpression(){
		this.id=null;
		this.init=null;
		this.kind=null;
		VariableExpression.__super.call(this);
	}

	__class(VariableExpression,'interpreter.VariableExpression',_super);
	var __proto=VariableExpression.prototype;
	__proto.run=function(scope){
		var name_1=this.id.name;
		var value=this.init ? this.init.run(scope):undefined;
		this.id.value=value;
		return null;
	}

	__proto.toString=function(){
		return this.kind+" "+this.id.toString()+"="+this.init;
	}

	return VariableExpression;
})(BaseExpression)



})(window,document,Laya);

if (typeof define === 'function' && define.amd){
	define('laya.core', ['require', "exports"], function(require, exports) {
        'use strict';
        Object.defineProperty(exports, '__esModule', { value: true });
        for (var i in Laya) {
			var o = Laya[i];
            o && o.__isclass && (exports[i] = o);
        }
    });
}